package com.sifeng.springcloud;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;

import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
@RestController
public class SpringcloudEurekaClientApplication {
	
	@Autowired
	DiscoveryClient discoveryClient;
	@Autowired
	RestTemplate restTemplate;
	
	@RequestMapping("/api-b/test")
	public String home() throws IOException {
		List<ServiceInstance> services = discoveryClient.getInstances("hello");
		ServiceInstance service = services.get(0);
		String host = service.getHost();
		int port = service.getPort();
		URL url = new URL("http://"+host+":"+port+"/api-a/hello");
		InputStream input = url.openStream();		
		byte[] result = new byte[10];
		IOUtils.readFully(input, result);
		System.out.println("%%%%%%%%%%%%%%%%%%%%%%: "+new String(result));
	    return "Hello world";
	}
	
	/**
	 * 功能与/test完全相同
	 * 代码简洁并且做了负载
	 * RestTemplate的其他功能？？研究一下
	 * 当/test2服务不可用或者阻塞（相应超时）的时候，应用程序不会没有相应，而是会调用熔断的回调处理方法。应用有比较的容错性
	 * 当/test2请求阻塞的情况下，会执行fallbackMethod方法
	 * @return
	 * @throws IOException
	 */
	@RequestMapping("/api-b/test2")
	@HystrixCommand(fallbackMethod = "hiError") 
	
	public String home2(String name) throws IOException { 
		String result = "";		
		result = restTemplate.getForObject("http://hello/api-b/hello", String.class,new HashMap<String,String>());		
		System.out.println("%%%%%%%%%%%%%%%%%%%%%%: "+result);
	    return "Hello world";
	}

	@RequestMapping("/api-a/hello")
	public String home3() {
		System.out.println("===============================:/api-a/hello Hello client");	
		return "Hello client";
	}
	
	@RequestMapping("/api-b/hello")
	public String home2() {
		System.out.println("===============================:/api-b/hello Hello client");	
		return "Hello client";
	}
	
    public String hiError(String name) {
        return "hi,"+name+",sorry,error!";
    }
	
	/**
	 * RestTemplate 负载均衡
	 * @return
	 */
	@Bean
	@LoadBalanced
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}
	
	public static void main(String[] args) {
//		SpringApplication.run(SpringcloudEurekaServerApplication.class, args);
		new SpringApplicationBuilder(SpringcloudEurekaClientApplication.class).web(true).run(args);
	}
}
